


import (WebsocketServer)    in "java/com/faros/lib/typeobj/nat/WebsocketServer";
import (HttpServer)         in "java/com/faros/lib/typeobj/nat/HttpServer";
import (ErrHandler)         in "java/com/faros/lib/typeobj/nat/ErrHandler";
import (Combatd)            in "adm/daemons/Combatd";
import (Task)               in "java/com/faros/lib/typeobj/nat/Task";
import (CronScheduler)      in "java/com/faros/lib/typeobj/nat/cron/CronScheduler";

static map cmds = ({});
static map objs = ({});
static var taskMgr;
static var cronScheduler;

static var initCmds(){
    var x = getDeepDir("cmds");
    for(number i;i < sizeof(x);i++){
        var v = x[i]["noneExt"];
        println("加载指令--->"+v);
        var n = explode( v,"/" );
        println("命令是" + n[0]);
        this::cmds[n[sizeof(n)-1]] = new(v);
    }
}

static number loadAllConf(){
    println("加载配置文件....");
    string sk = readFile("data/skills/skills.json");
    Combatd::skillsConf = jsonStrToMap(sk);
    println(Combatd::skillsConf);

}

static number login(var wss,string nid,string id,string passwd){

    string loginFile        = "data/login/"+subcut(id,0,1)+"/"+id;
    string userBodyFile    = "data/user/"+subcut(id,0,1)+"/"+id;
    string d = readFile(loginFile);
    if(!d){//没有就创建账号
         wss.send(nid,"你还没有创建账号，请输入create创建账号！格式 create 账号 密码 角色名称");
         return 0;
    }

    println(fmt("账号信息 %s %s",id,passwd));


    d = jsonStrToMap(d);
    (saveId,savePasswd)  = ( d["id"], d["passwd"] );
    varDump(d["id"]);
    if( id != saveId || passwd != savePasswd){
       wss.send(nid,fmt("账号或密码不正确 %s %s,%s %s",id,passwd,d["id"],d["passwd"]));
       return 0;
    }
     object user;
    if( (user = findUser(id)) ){
       bindConnect(user,nid,wss);
       tellObject(user,"你通过网络通道，钻进了你自己的身体。牛啊，牛啊。");
       return 1;
    }


     user = make("obj/user");
     user.setName("",([id]));//必须设置ID
//     string bodyData = readFile(userBodyFile);
    if( !user.restore() ){//创建
         wss.send(nid,"初始化角色restore失败！");
         destruct(user);//注意先销毁..否则内存泄漏

         user = this::createUserBody(nid,id,d["roleName"],passwd);
         if( !objectp(user) ){
            wss.send(nid,"初始化角色错误!");
            return 0;
         }
    }
    user.set("qi",user.query("maxQi"));

    user.delete("combatMessage");
    user.delete("combat/reward/pot");


    //注意顺序，先绑定再save
    bindConnect(user,nid,wss);
    user.save();

//


    user.move("d/chengdu/zygc");
    wss.send(nid,fmt("欢迎回来 %s。",user.query("name")));
}

static number bindConnect(object user,string nid,var wss){
       user.set("netChannel",wss);
       user.set("netAgentId",nid);
}

//创建账号
static number createAccount(var wss,string nid,string id,string roleName,string passwd){

    string loginFile = "data/login/%s/%s";
    loginFile =  fmt(loginFile,subcut(id,0,1),id);


    if( !writeFile(loginFile,toJsonStr(({"id":id,"passwd":passwd,"roleName":roleName}))) ){
        wss.send(nid,"账号创建失败，请联系管理员。");
        return 1;
    }

     wss.send(nid,"账号创建成功！");
     return 1;

}

static object createUserBody(string nid,string id,string roleName,string passwd){
    object user = make("obj/user");

    user.setName(roleName,([id]));
    user.set("passwd",passwd);
    user.set("money",9999999);


    user.set("str",20);
    user.set("con",20);
    user.set("int",20);
    user.set("dex",20);
    user.set("qi",200);
    user.set("maxQi",200);
    user.set("neili",100);
    user.set("maxNeili",100);
    return user;
}

static var startWss(){

     var wss = WebsocketServer::create("far",9011);
     wss.on("open",(nid)->{
        println(nid);
     });

      wss.on("message",(nid,msg)->{
        msg = replaceStr(msg,"\n","");
         (cmd,argv) = parseCommand(msg);

        println("指令是"+cmd+argv);



        //没有这个网络ID 但又不是登录
        if(!isLoginByNid(nid) && cmd!="login" && cmd!="create"){
            wss.send(nid,"请输入账号和密码登录!");
            return 0;
        }


         if(cmd=="login" && isLoginByNid(nid)){
            wss.send(nid,"你已登录了呀!");
            return 0;
         }
         var user;

         if( cmd=="create" && !isLoginByNid(nid) ){
            var instr = explode(argv," ");
            (id,passwd,roleName) = instr;
            return this::createAccount(wss,nid,id,roleName,passwd);
         }

         if( cmd=="login" && !isLoginByNid(nid) ){

                var instr = explode(argv," ");
                //跳过第一位，取多少位
                //argv 是参数内容
                (id,passwd) = instr;

                 println(fmt("login 指令执行 %s %s",id,passwd));

                //读取登录文件
                return this::login(wss,nid,id,passwd);

         }



            user = findUserOf(nid);

            if(!user) {
                println("没有登录");
                return 0;
            }

            this::cmds[cmd].main(user,argv);



      });

      wss.on("err",(nid,err)->{
         println(err);
      });

      wss.on("close",(nid)->{
         object u = netConn(nid);
         if( u ){
            u.disNetConn();
         }
         println(nid+"关闭了网络");
      });

     wss.start();
}

static var startHttpSvr(){

    number port = 9022;

//    // 创建一个 HTTP 服务器实例，监听指定端口，并添加一个处理根路径请求的动作
   var svr =   HttpServer::createServer(port);
    svr.setRoot(cwd()+"/www");
    svr.start();

    return svr;

}

static number main(string* args) {



    var deArg = deAppMainArgs(args);
    //根据启动参数 设置工作目录 默认工作目录 在应用的bin目录下
    if(sizeof(deArg)>0 ){
     println("工作目录" + deArg[0]);
     setCwd(deArg[0]);
    }

//    appendFile("log/x.txt","你好世界");
    //设置全局异常捕获
    ErrHandler::create((thread,err)->{
        println("捕获的异常:" + err);
    });

    this::cronScheduler = CronScheduler::create(5,100,30);
    //10s后启动定时任务 每5s执行一次
    addSchedulerTask(10,"task1","*/5 * * * * *,1 adm/daemons/Combatd testCron 参数1");

//
//   this::taskMgr = Task::create();
//
//    var oooppp = make("d/chengdu/npc/liapo");
//    callOut(oooppp,"test11111",3000,(["你好世界" ]));

//   this::taskMgr.submitDelayedTask("aaaa",10000,
//        ()->{
//
//            println("IO操作中。。。。");
//            return "任务完成，状态返回";
//        },
//        (e)->{
//            println("程序员: "+e);
//        }
//    );

   var wbSvr =  startHttpSvr();





    //加载所有配置文件
    loadAllConf();



    this::initCmds();

    this::startWss();

     var th =  createThread(()->{
          var prevTime;
          for(;;){

             var curTime = time();
             //prevTime 有问题，需要初始化
             if(  (curTime - prevTime) / 1000 % 60  >= 1 ){
                prevTime = time();

                foreach(k in this::objs){


                    if( !objectp(this::objs[k]) ){//对象列表中发现不是object，一般情况是有被销毁的对象
                        mapDelete(this::objs,k);
                        continue;
                    }


                    if( !this::objs[k].query("isLoad") ){
                        this::objs[k].load();
                        this::objs[k].set("isLoad",1);
                    }
                    string obName = this::objs[k].query("name");
                    if( !obName ){
                        obName =  this::objs[k].query("short");
                    }

//                   obName = this::objs[k].query("name") ? this::objs[k].query("name") : this::objs[k].query("short");
//                    println(fmt("%s(%s) 心跳",obName, this::objs[k].query("hasId")  ));
                    this::objs[k].heartbeat();






                    }
                }

             }


     });

    th.start();
    th.join();





//    println(ob);

    return;


}